今天我們來看個整合性例子,講述了Wordpress與MySQL的結合,同樣的做法分為兩種,第一種是透過EBS去實作它,第二種方法是透過EFS去實作它,那麼接下來我們就開始吧!
由於操作會用到PV,我們這裡小複習一下
複習傳送門:
這裡之前有提過,我們複習下:
Elastic Block Store (EBS) 是易於使用的高效能區塊儲存服務,專為與Elastic Compute Cloud (EC2) 搭配使用而設計,能以任何規模同時用於輸送量和交易密集型工作負載。各種工作負載 (如關聯式和非關聯式資料庫、企業應用程式、容器化的應用程式、大數據分析引擎、檔案系統和媒體工作流程) 廣泛部署在 EBS 上。
這邊示範如何透過設置EBS達到實作Wordpress結合MySQL的效果。
檢查既有的Namespace
$kubectl get namespaces
NAME STATUS AGE
default Active 17m
kube-public Active 17m
kube-system Active 17m
新增一個Namespace
$kubectl create namespace ns-eks
namespace/ns-eks created
檢查既有的Namespace
$kubectl get namespaces
NAME STATUS AGE
default Active 18m
kube-public Active 18m
kube-system Active 18m
ns-eks Active 13s
針對該Namespace,也就是ns-eks,可以發現他有Secret,它這裡有token供Dashboard使用
$kubectl get secret -n ns-eks
NAME TYPE DATA AGE
default-token-vkv4l kubernetes.io/service-account-token 3 3m17s
檢查StorageClass
$kubectl get storageclasses --all-namespaces
NAME PROVISIONER AGE
gp2 (default) kubernetes.io/aws-ebs 26m
發現到有gp2,而且這個位置是在我們新增的Namespace上:ns-eks
$kubectl get storageclasses -n ns-eks
NAME PROVISIONER AGE
gp2 (default) kubernetes.io/aws-ebs 28m
如果你發現沒有,可以參考下面新增
$vim gp2-storage-class.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp2
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
mountOptions:
- debug
這邊講解一下參數使用:
kind
:元件的種類,如:Pod、Deployment等等
apiVersion
:支援的API版本
metadata
:這個元件的附加資訊,像是名稱、標籤等等
provisioner
:存儲類的供應者,這裡是AWS
parameters
:一些其他參數,這裡有定義種類是gp2
reclaimPolicy
:指定的回收策略,預設是Delete,也就是當StorageClass掰掰的時候,它會將存儲卷刪掉,Retain則相反,會保留存儲卷
mountOptions
:掛載選項,對應被掛載的地方應要支援不然會失敗
如果k8s是1.10版:
$kubectl apply -f gp2-storage-class.yaml -n ns-eks
storageclass.storage.k8s.io "gp2" created
$kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' -n=ns-eks
不是的話就都不用做,應該剛開始就如同筆者畫面所顯示的
$kubectl get storageclasses -n ns-eks
NAME PROVISIONER AGE
gp2 (default) kubernetes.io/aws-ebs 28m
新增PersistentVolumeClaim
$vim pvcs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
接著apply它
$kubectl apply -f pvcs.yaml -n ns-eks
persistentvolumeclaim/mysql-pv-claim created
persistentvolumeclaim/wp-pv-claim created
檢查PVC狀態
$kubectl get pvc -n ns-eks
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pv-claim Bound pvc-6cc434b5-ecee-11e9-a674-0a822e4a246e 20Gi RWO gp2 39s
wp-pv-claim Bound pvc-6cf53941-ecee-11e9-a674-0a822e4a246e 20Gi RWO gp2 39s
注意到他們都已經Bound了,也就是已綁定的狀態,可以用囉!
我們檢查下AWS的EBS
有的!
新增一個Secret
$kubectl create secret generic mysql-pass --from-literal=password=eks-mysql-pw --namespace=ns-eks
secret/mysql-pass created
檢查Secret狀態
$kubectl get secret -n ns-eks
NAME TYPE DATA AGE
default-token-vkv4l kubernetes.io/service-account-token 3 67m
mysql-pass Opaque 1 66s
我們先新增一個YAML文件,部署MySQLl用的
$vim deploy-mysql.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
接著apply它
$kubectl create -f deploy-mysql.yaml -n ns-eks
service/wordpress-mysql created
deployment.apps/wordpress-mysql created
檢查Pod狀態
$kubectl get po -n ns-eks -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
wordpress-mysql-7d4fc77fdc-hfms5 1/1 Running 0 104s 192.168.15.32 ip-192-168-0-191.ap-southeast-1.compute.internal <none> <none>
可以注意到這個Pod是跑在ip-192-168-0-191.ap-southeast-1.compute.internal
這個節點上的
我們從AWS上對照看看
可以發現到狀態已經從available變成in-use
新增wordpress的Deployment
$vim deploy-wordpress-by-deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
接著Create
$kubectl create -f deploy-wordpress-by-deployment.yaml -n ns-eks
service/wordpress created
deployment.apps/wordpress created
檢查Pod狀態
$kubectl get po -n ns-eks -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
wordpress-dccb8668f-fs97z 1/1 Running 0 49s 192.168.51.242 ip-192-168-36-189.ap-southeast-1.compute.internal <none> <none>
wordpress-mysql-7d4fc77fdc-hfms5 1/1 Running 0 16m 192.168.15.32 ip-192-168-0-191.ap-southeast-1.compute.internal <none> <none>
這時候我們在切到AWS上去看下
可以發現到剛剛available的狀態變成in-use了
檢查Service狀態
$kubectl get svc -n ns-eks
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress LoadBalancer 10.100.215.253 aa6309614ecf211e98b110624e7825ce-1654920643.ap-southeast-1.elb.amazonaws.com 80:32086/TCP 7m34s
wordpress-mysql ClusterIP None <none> 3306/TCP 23m
接著我們透過EXTERNAL-IP去access它
有了,可以用囉!做一些簡單的設置就能登入了
登入後找Customize
輸入以下指令刪除
$kubectl delete -f deploy-wordpress-by-deployment.yaml -n ns-eks
service "wordpress" deleted
deployment.apps "wordpress" deleted
$kubectl delete -f deploy-mysql.yaml -n ns-eks
service "wordpress-mysql" deleted
deployment.apps "wordpress-mysql" deleted
刪除EBS
刪除PVC
$kubectl delete -f pvcs.yaml -n ns-eks
persistentvolumeclaim "mysql-pv-claim" deleted
persistentvolumeclaim "wp-pv-claim" deleted
刪除MySQL的Secret
$kubectl delete secret mysql-pass -n ns-eks
secret "mysql-pass" deleted
EFS和ENI有提過,我們複習下:
Elastic File System (EFS) :提供簡單、可擴展、全受管的彈性 NFS 檔案儲存,可與 AWS 雲端服務和內部部署資源搭配使用。其建置是為了要隨需擴展至數 PB,且不會中斷應用程式,可隨著新增和移除檔案自動擴展和縮減,無須佈建和管理容量來適應增長。
EFS 提供兩種儲存類別:標準儲存類別和不常存取儲存類別 (EFS IA)。EFS IA 針對每天未存取的檔案提供成本優化的性價比。
Elastic Network Interface(ENI):彈性網路界面是代表虛擬網路卡之 VPC 中的邏輯聯網元件。
可在帳戶中建立並設定網路界面,然後將它們連接到VPC 中的執行個體。
我們先到AWS介面操作,切換到EFS
VPC和Security groups要選eks相關的,好了下一步
新增一個Tag
好了會長這樣
接著我們來檢查下ENI的狀態
OK,有建立與EFS的連接
新增Namespace並確認
$kubectl create namespace ns-eks-efs
namespace/ns-eks-efs created
$kubectl get namespace
NAME STATUS AGE
default Active 179m
kube-public Active 179m
kube-system Active 179m
ns-eks Active 161m
ns-eks-efs Active 51s
建立efs-provisioner
efs-id和server的地方依照建立的EFS修改
$vim create-efs-provisioner.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: efs-provisioner
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: efs-provisioner
spec:
containers:
- name: efs-provisioner
image: quay.io/external_storage/efs-provisioner:v0.1.0
env:
- name: FILE_SYSTEM_ID
value: fs-d8c8b999
- name: AWS_REGION
value: ap-southeast-1
- name: PROVISIONER_NAME
value: eks-course/aws-efs
volumeMounts:
- name: pv-volume
mountPath: /persistentvolumes
volumes:
- name: pv-volume
nfs:
server: fs-d8c8b999.efs.ap-southeast-1.amazonaws.com
path: /
好了apply它
$kubectl apply -f create-efs-provisioner.yaml -n ns-eks-efs
deployment.extensions/efs-provisioner created
新增RBAC
$vim create-rbac.yaml
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nfs-provisioner-role-binding
subjects:
- kind: ServiceAccount
name: default
namespace: ns-eks-course-efs
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
好了apply
$kubectl apply -f create-rbac.yaml -n ns-eks-efs
clusterrolebinding.rbac.authorization.k8s.io/nfs-provisioner-role-binding created
建立存儲
$vim create-storage.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: aws-efs
provisioner: eks-course/aws-efs
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: efs-wordpress
annotations:
volume.beta.kubernetes.io/storage-class: "aws-efs"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: efs-mysql
annotations:
volume.beta.kubernetes.io/storage-class: "aws-efs"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
好了apply它
$kubectl apply -f create-storage.yaml -n ns-eks-efs
storageclass.storage.k8s.io/aws-efs created
persistentvolumeclaim/efs-wordpress created
persistentvolumeclaim/efs-mysql created
接下來的這兩步與前面的EBS類似
新增一個Secret
$kubectl create secret generic mysql-pass --from-literal=password=eks-mysql-pw --namespace=ns-eks-efs
secret/mysql-pass created
接著apply
$kubectl create -f deploy-mysql.yaml -n ns-eks-efs
service/wordpress-mysql created
deployment.apps/wordpress-mysql created
我們同樣也可以檢查他的狀態,無論是從命令行或是AWS
Create Wordpress的Deployment
$kubectl create -f deploy-wordpress-by-deployment.yaml -n ns-eks
service/wordpress created
deployment.apps/wordpress created
我們同樣也可以檢查集群及AWS狀態
最後可以透過DNS去access它,得到相同的結果
就介紹到這邊囉!
今天我們看到了EBS和EFS不同的使用方式,主要是前半段不同,後半段在設置MySQL和Wordpress基本上大同小異,在設置EBS的時候,我們可以發現,它是綁定EC2的,也就是說一個EBS會對應一台EC2,另外也因為它綁定的緣故,所以它不能跨區域(Area Zone)。再來我們看到了EFS,它建立的時候,會自動幫我們建立一個ENI,並在部署前必須要設置provisioner去串接k8s元件,因為它算是一個NFS的檔案系統(File System),所以它可以做到跨區域,不過也不是沒有缺點的,它比EBS貴,因此我們必須參考我們的使用需求,進而去決定我們想要使用的方案。明天會開始介紹整合性相關的內容,敬請期待!我們明天見。
本文同步刊載於https://github.com/x1y2z3456/ironman
感謝您撥冗閱讀此文章,不喜勿噴,有任何問題建議歡迎下方留言:)
說個笑話,希望我能寫滿30天啊(笑